#ifndef _ARCH_CONTROL_H_
#define _ARCH_CONTROL_H_

/********************************************************************
 * ArchControl.h
 * 
 * Descripcion :Esta clase representa un archivo de control de registros
 * fijos del tipo [unsigned int] con organizacion secuencial, en bloques.
*********************************************************************/

#include "archivo.h"
#include "buffer.h"

#define TAM_REG 4

class ArchControl : public Archivo {
	
	public:
	
		ArchControl(std::string& nombre, unsigned int tam_bloque);
	
		virtual ~ArchControl();
		
		/*
		 * Crea el archivo de control, lo inicializa y lo abre.
		 * Si el archivo ya estaba creado arroja una excep.
		 */
		virtual void crear() throw(ExcepCreandoArch);
	
		//IMPLEMENTO LOS METODOS DE ARCHIVO
		
		virtual void abrir() throw(ExcepAbriendoArch);
		
		virtual void cerrar();
 													
		virtual void eliminar();
		
		TiposArchivo get_tipo_archivo();
		
		virtual unsigned int get_espacio_libre()  throw(ExcepArchCerrado, ExcepLeerBloque);
		
		/*
		 * Dado un valor a setear, coloca ese valor en un slot de registro fijo
		 * cuyo valor es el pasado por param.
		 */
		void set_valor(unsigned int num_slot, unsigned int valor);
		
		/*
		 * Devuelve el valor contenido en el slot cuyo numero es el pasado por param
		 */
		unsigned int get_valor(unsigned int num_slot);
		
		/*
		 * Dado un valor, agrega una entrada de
		 * al final del archivo, en el ultimo bloque.
		 * Si el ultimo esta lleno crea un nuevo bloque y lo coloca alli.
		 */	
		virtual void append(unsigned int valor) throw(ExcepArchCerrado, ExcepEscribirBloque,ExcepLeerBloque);
		
		/*
		 * Elimina la ultima entrada del archivo.
		 * Si el bloque queda vacio lo trunca.
		 */
		virtual void borrar_ultimo();
		
		/*
		 * Devuelve la cantidad de elementos que controla. Es decir, la
		 * cantidad de registros que tiene que corresponden a elementos
		 * controlados
		 */ 
		unsigned int get_cantidad_elementos();

	protected:
	
		/*
		 * Crea un nuevo bloque vacio en el archivo y lo escribe.
		 */
		void crear_bloque() throw(ExcepEscribirBloque);
		
		/*
		 * Almacena la cantidad actual de bloques de este archivo en el disco.
		 */
		void set_cant_bloques_header(unsigned int cant);
		
		/*
		 * Recupera la cant de bloques de este archivo desde el disco.
		 */
		unsigned int get_cant_bloques_header();
		
		/*
		 * Dado un num de slot, devuelve el num bloque
		 * que contiene a ese slot.
		 */
		unsigned int slot_to_nbloque(unsigned int slot);
		
		/*
		 * Dado un num de slot, devuelve el offset del mismo dentro del bloque
		 * que contiene a ese slot.
		 */
		unsigned int slot_to_despl(unsigned int slot);
		
		/*
		 * Dado un bloque y un offset dentro del archivo de espacios libres,
		 * devuelve el num de slot.
		 */
		unsigned int nbloque_to_slot(unsigned int cont_bloques, unsigned int pos_reg);
};

#endif
